package org.javahispano.javacup.tacticas_aceptadas.kalimero.org.jpenalta.javacup.tactica.kalimero;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import javax.print.attribute.standard.DateTimeAtCompleted;

import org.javahispano.javacup.modelo.*;

public class KalimeroTactica implements Tactica {

	private double alturaBalon = 0;

	KalimeroDetalle detalle = new KalimeroDetalle();
	Posicion alineacion1[] = new Posicion[] {
			new Posicion(0.2595419847328244, -50.41044776119403),
			new Posicion(-11.16030534351145, -31.082089552238806),
			new Posicion(11.16030534351145, -31.6044776119403),
			new Posicion(27.251908396946565, -27.94776119402985),
			new Posicion(-29.84732824427481, -26.902985074626866),
			new Posicion(8.564885496183205, -7.574626865671642),
			new Posicion(-10.641221374045802, -7.052238805970149),
			new Posicion(27.251908396946565, 4.440298507462686),
			new Posicion(-29.32824427480916, 3.3955223880597014),
			new Posicion(-0.2595419847328244, 19.067164179104477),
			new Posicion(-0.2595419847328244, 30.78358208955224) };
	Posicion alineacion2[] = new Posicion[] {
			new Posicion(0.2595419847328244, -50.41044776119403),
			new Posicion(28.290076335877863, -28.470149253731343),
			new Posicion(-0.16030534351145, -31.082089552238806),
			new Posicion(-28.290076335877863, -28.470149253731343),
			new Posicion(-12.16030534351145, -10.6044776119403),
			new Posicion(12.16030534351145, -10.3059701492537314),
			new Posicion(-10.641221374045802, 15.7835820895522387),
			new Posicion(10.603053435114505, 15.992537313432837),
			new Posicion(-27.251908396946565, 31.6044776119403),
			new Posicion(0., 39.559701492537314),
			new Posicion(27.69465648854962, 31.992537313432837) };
	Posicion alineacion3[] = new Posicion[] {
			new Posicion(0.2595419847328244, -50.41044776119403),
			new Posicion(-11.16030534351145, -35.78358208955224),
			new Posicion(12.717557251908397, -35.26119402985075),
			new Posicion(28.290076335877863, -28.470149253731343),
			new Posicion(-28.290076335877863, -28.470149253731343),
			new Posicion(14.793893129770993, -18.544776119402986),
			new Posicion(-17.389312977099234, -19.58955223880597),
			new Posicion(-23.618320610687025, -0.7835820895522387),
			new Posicion(5.969465648854961, -5.485074626865671),
			new Posicion(0.2595419847328244, -0.26119402985074625),
			new Posicion(22.580152671755727, -1.3059701492537314) };
	Posicion alineacion4[] = new Posicion[] {
			new Posicion(0.2595419847328244, -50.41044776119403),
			new Posicion(-11.16030534351145, -35.78358208955224),
			new Posicion(12.717557251908397, -35.26119402985075),
			new Posicion(28.290076335877863, -28.470149253731343),
			new Posicion(-28.290076335877863, -28.470149253731343),
			new Posicion(14.793893129770993, -18.544776119402986),
			new Posicion(-17.389312977099234, -19.58955223880597),
			new Posicion(-23.618320610687025, -0.7835820895522387),
			new Posicion(6.4885496183206115, -6.529850746268657),
			new Posicion(-6.4885496183206115, -6.529850746268657),
			new Posicion(22.580152671755727, -1.3059701492537314) };

	Posicion alineacion5[] = new Posicion[] {
			new Posicion(0.2595419847328244, -50.41044776119403),
			new Posicion(-0.16030534351145, -31.082089552238806),
			new Posicion(28.290076335877863, -28.470149253731343),
			new Posicion(-28.290076335877863, -28.470149253731343),
			new Posicion(-11.16030534351145, -10.6044776119403),
			new Posicion(11.16030534351145, -10.3059701492537314),
			new Posicion(-20.641221374045802, 15.7835820895522387),
			new Posicion(20.603053435114505, 15.992537313432837),
			new Posicion(-17.251908396946565, 38.6044776119403),
			new Posicion(0.641221374045802, 31.559701492537314),
			new Posicion(17.69465648854962, 38.992537313432837) };

	private double distanciaMax = 0.;

	public TacticaDetalle getDetalle() {
		return detalle;
	}

	int cambia = 0;

	public Posicion[] getPosicionSaca(SituacionPartido sp) {
		return alineacion3;
	}

	public Posicion[] getPosicionRecive(SituacionPartido sp) {
		return alineacion4;
	}

	Random rand = new Random();
	LinkedList<Comando> comandos = new LinkedList<Comando>();

	UtilsKalimero2 utils = null;

	/**
	 * Aquí comienza la chica
	 * 
	 * 
	 */
	public List<Comando> ejecutar(SituacionPartido sp) {
		boolean log = false;
		if (utils == null) {
			utils = new UtilsKalimero2(this.getDetalle());
		}
		utils.setSituacionPartido(sp);
		utils.prepara();

		Posicion[] alineacion = this.alineacion2;
	
		// if (sp.golesPropios() < sp.golesRival() || sp.) {
		// alineacion = this.alineacion5;
		// }

		if (sp.balon().getY() > 45 && sp.balon().getY() < 54) {
			utils.log(log, " posicion pelota: " + sp.balon());
			utils.log(log, " altura: " + sp.alturaBalon());
		}
		comandos.clear();

		// MOVERSE

		int jugadorMasCercano = utils.getDestinoBalon().indiceMasCercano(
				sp.misJugadores());

		Posicion irA = utils.getDestinoBalon();

		// if (utils.getDestinoBalon().getY() > Constantes.penalSup.getX()) {
		// irA = utils.getRemateCabeza();
		// }

		if (!UtilsKalimero2.isDentroCampo(utils.getDestinoBalon())) {

			irA = utils.getRemateCabeza();

		} else {

			int iteracionesJugadorPM = utils.iteracionesEnLlegar(
					jugadorMasCercano, utils.getPuntoMedioRemate());
			int iteracionesJugadorDes = utils.iteracionesEnLlegar(
					jugadorMasCercano, utils.getDestinoBalon());
			int iteracionesJugadorCab = utils.iteracionesEnLlegar(
					jugadorMasCercano, utils.getRemateCabeza());

			utils.log(false, "iter PM" + iteracionesJugadorPM + " iter Cab "
					+ iteracionesJugadorCab + " Iter Des "
					+ iteracionesJugadorDes);
			if (iteracionesJugadorPM - utils.getIteracionesCabeza() > 2) {
				if (iteracionesJugadorPM > 1) {
					irA = utils.getPuntoMedioRemate();
				} else {
					irA = sp.misJugadores()[jugadorMasCercano];
				}
			} else {
				int rivalDestinoBalon = utils.getDestinoBalon()
						.indiceMasCercano(sp.rivales());
				int rivalRemateCabeza = utils.getRemateCabeza()
						.indiceMasCercano(sp.rivales());

				if (utils.getDestinoBalon().distancia(
						sp.rivales()[rivalDestinoBalon]) < Constantes.DISTANCIA_CONTROL_BALON
						|| utils.getDestinoBalon().distancia(
								sp.rivales()[rivalRemateCabeza]) < Constantes.DISTANCIA_CONTROL_BALON) {
					irA = utils.getRemateCabeza();
				} else {
					if (utils.getIteracionesDestinoBalon() > 2) {
						irA = sp.misJugadores()[jugadorMasCercano];
					} else {
						irA = utils.getDestinoBalon();
					}
				}
			}
		}

		for (int i = 1; i < sp.misJugadores().length; i++) {
			if (i == jugadorMasCercano) {
				comandos.add(new ComandoIrA(i, irA));
			} else {
				comandos.add(new ComandoIrA(i, alineacion[i]));
			}
		}

		// EL PORTERO
		if (0 == jugadorMasCercano) {
			
			utils.log(false, " CP " + utils.iteracionesEnLlegar(0, utils.getRemateCabezaPortero()) + " < " + utils.getIteracionesCabezaPortero() );
			utils.log(false, " C " + utils.iteracionesEnLlegar(0, utils.getRemateCabeza() )+ " < " + utils.getIteracionesCabeza() );
			utils.log(false, " Des " + utils.iteracionesEnLlegar(0, utils.getDestinoBalon()) + " < " + utils.getIteracionesDestinoBalon()  );
			
			if (utils.iteracionesEnLlegar(0, utils.getRemateCabezaPortero()) <= utils
					.getIteracionesCabezaPortero()
					&& utils.getRemateCabezaPortero().getY() > Constantes.centroArcoInf.getY() -  Constantes.DISTANCIA_CONTROL_BALON_PORTERO) {
				comandos.add(new ComandoIrA(0, utils.getRemateCabezaPortero()));
				
			} else if (utils.iteracionesEnLlegar(0, utils.getRemateCabeza()) <= utils
					.getIteracionesCabeza()
					&& utils.getRemateCabeza().getY() > Constantes.centroArcoInf.getY() -  Constantes.DISTANCIA_CONTROL_BALON_PORTERO) {
				comandos.add(new ComandoIrA(0, utils.getRemateCabeza()));
				
			} else if (utils.iteracionesEnLlegar(0, utils.getDestinoBalon()) <= utils
					.getIteracionesDestinoBalon()
					&& utils.getDestinoBalon().getY() < Constantes.centroArcoInf.getY() -  Constantes.DISTANCIA_CONTROL_BALON_PORTERO) {
				comandos.add(new ComandoIrA(0, utils.getDestinoBalon()));
				
			} else {
				
				if (sp.alturaBalon() == 0 
						&& Math.abs(utils.balonCruzaPorteria()) < Constantes.posteDerArcoInf
								.getX() 
						&& !utils.balonParado()) {
					comandos.add(new ComandoIrA(0, new Posicion(utils
							.balonCruzaPorteria(), Constantes.centroArcoInf
							.getY())));
				} else if(  utils.getDestinoBalon().getY() < Constantes.centroArcoInf
							.getY() ){
					comandos.add(new ComandoIrA(0, new Posicion(utils
							.balonCruzaPorteria(), Constantes.centroArcoInf
							.getY())));
				}else{
					
					comandos.add(new ComandoIrA(0, utils.getDestinoBalon()));
					
				}
				
			}
		} else {
			if( Math.abs(utils.balonCruzaPorteria()) < Constantes.posteDerArcoSup
								.getX()){
			comandos.add(new ComandoIrA(0, new Posicion(utils
					.balonCruzaPorteria(), Constantes.centroArcoInf.getY() + Constantes.DISTANCIA_CONTROL_BALON_PORTERO)));
			}else{
				comandos.add( new ComandoIrA(0,alineacion[0]));
			}
		}

		// PASAR
		int rematan[] = sp.puedenRematar();
		// recorre los jugadores que pueden rematar
		for (int i : rematan) {
			int pasarA = utils.pasarA(i, sp.misJugadores(), sp.rivales());

			if (pasarA == 11) { // tiro a puerta

				if (utils.avanceConBalon(i, Constantes.centroArcoSup)) {
					comandos.add(new ComandoGolpearBalon(i));
					comandos.add(new ComandoIrA(i, Constantes.centroArcoSup));
				} else {
					if (sp.misJugadores()[i]
							.distancia(Constantes.centroArcoSup) < 10) {
						comandos.add(new ComandoGolpearBalon(i, utils
								.anguloTiroAGol(i), 1, false));
					}
					comandos.add(new ComandoGolpearBalon(i, utils
							.anguloTiroAGol(i), utils.fuerzaTiroAGol(i, sp
							.alturaBalon()), true));
				}
			} else { // paso al jugador pasarA
				if (utils.avanceConBalon(i, alineacion[pasarA]) && i != 0) {
					comandos.add(new ComandoGolpearBalon(i));
					comandos.add(new ComandoIrA(i, alineacion[pasarA]));
				} else {
					comandos.add(new ComandoGolpearBalon(i, alineacion[pasarA],
							utils.fuerzaTiro(i, alineacion[pasarA]
									.distancia(utils.getDestinoBalon()), 30.,
									0., 0.), 30));
					// System.out.println( i + " pasa a " + pasarA +
					// " posicion Balon " + posicionBalon + " distancia " +
					// sp.balon().distancia(destinoBalon));
				}
			}
		}

		return comandos;
	}

}
